package com.myrpc.provider.impl;

import com.myrpc.provider.InterfaceProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

import java.util.HashMap;
import java.util.Map;

@Component(value = "DefaultInterfaceProvider")
@Slf4j
public class DefaultInterfaceProvider implements ApplicationContextAware, InterfaceProvider {
    /**
     * SpringIoc容器
     */
    private ApplicationContext applicationContext;
    /**
     * 可被调用接口存储
     * Key = 接口类名
     * Value = 接口Bean对象
     */
    private Map<String, Object> storage;

    public DefaultInterfaceProvider(){

    }

    /**
     * 在此方法调用时初始化storage
     * @param applicationContext the ApplicationContext object to be used by this object
     * @throws BeansException
     */
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
        //获得项目Ioc容器中的全部Controller接口
        Map<String, Object> beansWithAnnotation = applicationContext.getBeansWithAnnotation(Controller.class);
        this.storage = new HashMap<>();
        for(Map.Entry<String, Object> entry : beansWithAnnotation.entrySet()){
            String[] splitOfClassName = entry.getValue().getClass().getName().split("\\.");
            this.storage.put(splitOfClassName[splitOfClassName.length - 1], entry.getValue());
        }
        log.info("The storage of the Controller that can be called remotely is loaded");
    }

    /**
     * 添加一个接口
     *
     * @param interfaceClass 可能被远程调用的接口
     */
    @Override
    @Deprecated
    public void addInterface(Class<?> interfaceClass) {
        //一个无效的方法
    }

    /**
     * 获得存储的所有接口
     *
     * @return 所有存储的接口
     */
    @Override
    public Map<String, Object> getAllInterface() {
        if (this.storage == null){
            throw new RuntimeException("storage 尚未初始化");
        }
        return this.storage;
    }

    /**
     * 判断是否存在接口名称与参数相同的接口
     *
     * @param name 目标接口的名字
     * @return 判断结果
     */
    @Override
    public boolean isExistByName(String name) {
        return this.storage.containsKey(name);
    }

    /**
     * 获得接口的Bean对象
     *
     * @param name 接口名称
     * @return 接口对象
     */
    @Override
    public Object getInterfaceByName(String name) {
        return this.storage.get(name);
    }
}
